package com.mm.cloth;

import android.app.Application;
import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;

import com.mm.cloth.api.ApiClient;
import com.mm.cloth.utils.CrashHandler;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * 应用程序Application类
 * 用于初始化全局组件
 */
public class MMClothApplication extends Application {

    private static final String TAG = "MMClothApplication";

    @Override
    public void onCreate() {
        super.onCreate();

        try {
            // 初始化崩溃处理器（最先初始化）
            CrashHandler.getInstance().init(this);

            // 移除ONNX模型信息打印功能，因为API不兼容
            // printOnnxModelInfo();

            // 提前获取域名和端口配置
            fetchBaseUrlConfiguration();

            // 初始化ApiClient
            ApiClient.init(this);

        } catch (Exception e) {
            Log.e(TAG, "应用程序初始化失败", e);
            // 不抛出异常，让应用继续运行
        }
    }

    private void printOnnxModelInfo() {
        // 移除ONNX模型信息打印功能，因为API不兼容
        // OnnxModelInfoExtractor.printModelIOInfo(this, "modnet.onnx");
    }

    private void fetchBaseUrlConfiguration() {
        // 使用CountDownLatch确保在后台线程中完成网络请求后再继续
        final CountDownLatch latch = new CountDownLatch(1);
        final AtomicReference<String[]> result = new AtomicReference<>();
        
        // 在后台线程中获取域名和端口
        new Thread(() -> {
            String[] hostAndPort = fetchActualDomainAndPortSync();
            result.set(hostAndPort);
            latch.countDown();
        }).start();
        
        try {
            // 等待后台线程完成
            latch.await();
            
            String[] hostAndPort = result.get();
            if (hostAndPort != null && hostAndPort.length == 2) {
                // 直接使用ApiClient的公共变量
                ApiClient.BASE_HOST = hostAndPort[0];
                ApiClient.BASE_PORT = Integer.parseInt(hostAndPort[1]);
            }
        } catch (InterruptedException e) {
            Log.e(TAG, "等待域名和端口配置时被中断", e);
            Thread.currentThread().interrupt();
        }
    }

    private String[] fetchActualDomainAndPortSync() {
        try {
            // 使用OkHttpClient发起网络请求
            OkHttpClient client = new OkHttpClient.Builder()
                    .followRedirects(false) // 禁止自动跟随重定向
                    .build();

            Request request = new Request.Builder()
                    .url("http://server.layshen.fun")
                    .build();

            Response response = client.newCall(request).execute();

            if (response.isSuccessful() || response.code() == 301) {
                // 获取重定向地址
                String location = response.header("Location");
                response.close();

                if (location != null) {
                    // 解析重定向地址中的域名和端口
                    URI uri = URI.create(location);
                    String host = uri.getHost();
                    int port = uri.getPort();
                    
                    if (port != -1) {
                        return new String[]{host, String.valueOf(port)};
                    } else {
                        // 如果没有指定端口，根据协议设置默认端口
                        if ("https".equals(uri.getScheme())) {
                            return new String[]{host, "443"};
                        } else {
                            return new String[]{host, "80"};
                        }
                    }
                }
            } else {
                Log.w(TAG, "未能获取到有效的域名和端口，使用默认配置");
                response.close();
                return null;
            }
        } catch (Exception e) {
            Log.e(TAG, "获取实际域名和端口时发生异常", e);
            return null;
        }
        
        // 如果以上方法都失败，返回默认配置
        return new String[]{"default-host.com", "8080"};
    }

    private String readConfigFromAssets(AssetManager assetManager) {
        try {
            // 打开assets目录下的modnet.onnx文件
            InputStream is = assetManager.open("modnet.onnx");
            
            // 创建缓冲区并读取文件内容
            byte[] buffer = new byte[is.available()];
            is.read(buffer);
            
            // 关闭输入流
            is.close();
            
            // 将文件内容转换为字符串（对于二进制文件，这可能不是最佳做法）
            return new String(buffer);
            
        } catch (IOException e) {
            Log.e(TAG, "读取assets文件时发生错误", e);
            return null;
        }
    }

}
